package com.iflytek.universitymanagement.prediect;

import com.iflytek.universitymanagement.mapper.StudentMapper;
import com.iflytek.universitymanagement.mapper.CourseMapper;
import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.CellUtil;
import org.apache.hadoop.hbase.client.*;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.hbase.TableName;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@Service
public class HBaseService {

    private static final String TABLE_NAME = "student_failure_predictions"; // HBase 表名
    private static final Logger logger = LoggerFactory.getLogger(HBaseService.class);

    @Autowired
    private Connection connection;

    @Autowired
    private StudentMapper studentMapper; // 查询学生 ID

    @Autowired
    private CourseMapper courseMapper; // 查询课程名称

    // 根据学生姓名查询预测数据
    public List<PredictionResult> getPredictionByStudentName(String studentName) throws IOException {
        // 通过学生姓名查询学生 ID
        Integer studentId = studentMapper.getStudentIdByName(studentName);
        if (studentId == null) {
            logger.error("未找到学生姓名为 {} 的学生ID", studentName);
            throw new RuntimeException("学生不存在");
        }
        logger.info("根据学生姓名 {} 查询到学生ID: {}", studentName, studentId);

        // 根据学生 ID 查询预测数据
        return getPredictionByStudentId(studentId);
    }

    // 根据学生 ID 查询预测数据
    public List<PredictionResult> getPredictionByStudentId(Integer studentId) throws IOException {
        if (studentId == null) {
            logger.error("学生ID为空");
            throw new RuntimeException("学生ID不能为空");
        }

        // 通过学生ID从HBase获取所有数据
        Table table = connection.getTable(TableName.valueOf(TABLE_NAME));
        Scan scan = new Scan();
        scan.setRowPrefixFilter(Bytes.toBytes(studentId.toString()));  // 使用学生 ID 作为前缀过滤
        ResultScanner scanner = table.getScanner(scan);

        List<PredictionResult> predictionResults = new ArrayList<>();

        for (Result result : scanner) {
            String courseName = null;
            float attendanceRate = 0.0f;
            float homeworkCompletionRate = 0.0f;
            double riskOfFailure = 0.0; // 新增挂科概率字段
            String predictionStatus = "没挂科";  // 默认值是 "没挂科"
            // 获取该行中的所有列（即课程数据）

            for (Cell cell : result.listCells()) {
                String column = Bytes.toString(CellUtil.cloneQualifier(cell));
                byte[] value = CellUtil.cloneValue(cell);  // 获取该列的字节值

                if ("course_id".equals(column)) {
                    // 确保 course_id 是 int 类型，添加额外的验证
                    if (value.length == 4) {  // 确保字节数组长度为4（一个整数）
                        int courseId = Bytes.toInt(value);
                        courseName = courseMapper.findCourseNameById(courseId); // 根据课程ID查询课程名称
                        if (courseName == null) {
                            logger.error("未找到课程ID {} 对应的课程名称", courseId);
                            throw new RuntimeException("未找到课程ID " + courseId + " 的课程名称");
                        }
                        logger.info("查询到课程ID {} 对应的课程名称: {}", courseId, courseName);
                    } else if (value.length == 1) {  // 如果是字符串或其他类型的字节数组
                        String courseIdStr = Bytes.toString(value);
                        try {
                            int courseId = Integer.parseInt(courseIdStr); // 转换字符串为整数
                            courseName = courseMapper.findCourseNameById(courseId); // 根据课程ID查询课程名称
                            if (courseName == null) {
                                logger.error("未找到课程ID {} 对应的课程名称", courseId);
                                throw new RuntimeException("未找到课程ID " + courseId + " 的课程名称");
                            }
                            logger.info("查询到课程ID {} 对应的课程名称: {}", courseId, courseName);
                        } catch (NumberFormatException e) {
                            logger.error("课程ID转换失败, 存储的值为: {}", Bytes.toString(value));
                        }
                    } else {
                        logger.error("Invalid course_id length: {}", value.length);
                    }
                }

                if ("attendance_rate".equals(column)) {
                    // 确保 attendance_rate 是 float 类型
                    attendanceRate = getCellValueAsFloat(value);
                }

                if ("homework_completion_rate".equals(column)) {
                    // 确保 homework_completion_rate 是 float 类型
                    homeworkCompletionRate = getCellValueAsFloat(value);
                }

                if ("risk_of_failure".equals(column)) {
                    // 确保 value 被正确解析为 double 类型
                    riskOfFailure = getCellValueAsDouble(value);
                    logger.info("成功解析 risk_of_failure 值: {}", riskOfFailure);
                }

                if ("prediction".equals(column)) {
                    // 获取 prediction 值，并根据值映射为 "挂科" 或 "没挂科"
                    predictionStatus = getPredictionStatus(value);
                    logger.info("读取到的挂科预测值：{}", predictionStatus);
                }
            }

            // 创建 PredictionResult 并加入到结果列表
            if (courseName != null) {
                PredictionResult predictionResult = new PredictionResult(courseName, attendanceRate, homeworkCompletionRate, predictionStatus ,riskOfFailure);
                predictionResults.add(predictionResult);
            }
        }

        return predictionResults;
    }

    private double getCellValueAsDouble(byte[] value) {
        if (value == null || value.length == 0) {
            return 0.0; // 默认值
        }
        try {
            // 将字节数组转换为字符串，然后解析为 double
            return Double.parseDouble(Bytes.toString(value));
        } catch (NumberFormatException e) {
            System.err.println("无法将值解析为 double 类型：" + Bytes.toString(value));
            return 0.0; // 如果解析失败，返回默认值
        }
    }


    // 从字节数组获取 float 类型的值
    private float getCellValueAsFloat(byte[] value) {
        if (value != null && value.length > 0) {
            try {
                return Float.parseFloat(Bytes.toString(value));
            } catch (NumberFormatException e) {
                logger.error("Unable to convert byte array to float: {}", Bytes.toString(value));
            }
        }
        return 0.0f; // 如果转换失败，返回默认值 0.0f
    }


    // 将 prediction 的数值转换为 "挂科" 或 "没挂科"
    private String getPredictionStatus(byte[] value) {
        if (value != null && value.length > 0) {
            try {
                float predictionValue = Float.parseFloat(Bytes.toString(value));  // 将字节数组转换为 float
                if (predictionValue == 1.0f) {
                    return "可能挂科";
                } else if (predictionValue == 0.0f) {
                    return "没挂科";
                }
            } catch (NumberFormatException e) {
                logger.error("无法转换 prediction 值: {}", Bytes.toString(value));
            }
        }
        return "没挂科";  // 默认返回 "没挂科"
    }
}
